import app from '@system.app'
import router from '@system.router'

import { RouteConfig, PageInfo } from "@src/json/routeConfig.js"


import { UserDataModel, UserDeviceDataModel, UserLocalDataModel } from "@ytsdk/sdks/tactics_sdk/tactics_data_model.js"
import { TacticsSdk } from "@ytsdk/sdks/tactics_sdk/tactics_sdk.js"
import { PopUpInfo } from "@ytsdk/sdks/tactics_sdk/popup_data_model.js"
import { AdControl } from "@ytsdk/ad_pool/ad_control/ad_control.js"
import { CONST_CODE } from "@ytsdk/utils/ytsdk_const.js"
import { ReportUtil } from '@ytsdk/sdks/report_sdk/report_util.js'
import { ReportControl } from '@ytsdk/sdks/report_sdk/report_control.js'
import { StorageUtils } from "@ytsdk/utils/storage_util.js"

export let PublicData = {
    popInfo: null,
    isAdControl: true,
    isShowPopup: false,
    isShowPagePool: false,
    isAllowBackPress: false,
    isAllowClosePress: false,
    isAllowNegPress: false,


    tacticsSDK: null,
    reportSDK: null,
    userData: null,
    userDeviceData: null,
    userLocalData: null,
    routerConfig: null,

    popCodeLast: ""
}

export class PageUtil {
    constructor(cxt) {
        this.cxt = cxt
    }

    //初始化基础数据
    async initUserDatas() {

        $YTLOG(CONST_CODE.LOG_VIEW, "时间——开始初始化用户数据:", Date.now())

        //初始化数据
        if (!$YTSDK.userData) {
            $YTSDK.userData = await UserDataModel.initialization(this.cxt.$page.query)
            $YTLOG(CONST_CODE.LOG_VIEW, "用户基础数据:", $YTSDK.userData)
            $YTLOG(CONST_CODE.LOG_VIEW, "时间——用户基础数据:", Date.now())

        }

        if (!$YTSDK.userDeviceData) {

            $YTSDK.userDeviceData = await UserDeviceDataModel.initialization()
            $YTLOG(CONST_CODE.LOG_VIEW, "设备基础数据:", $YTSDK.userDeviceData)

            $YTLOG(CONST_CODE.LOG_VIEW, "时间——设备基础数据:", Date.now())
        }

        if (!$YTSDK.userLocalData) {
            $YTSDK.userLocalData = await UserLocalDataModel.initialization($YTSDK.userData)
            $YTLOG(CONST_CODE.LOG_VIEW, "本地持久化数据:", $YTSDK.userLocalData)

            $YTLOG(CONST_CODE.LOG_VIEW, "时间——本地持久化数据:", Date.now())
        }
    }


    //初始化页面数据
    async initSDK() {
        //1.策略SDK


        if (!$YTSDK.tacticsSDK) {
            $YTLOG(CONST_CODE.LOG_VIEW, "时间——策略初始化开始:", Date.now())

            $YTSDK.tacticsSDK = await TacticsSdk.initialization($YTSDK.userData, $YTSDK.userDeviceData, $YTSDK.userLocalData)
            $YTLOG(CONST_CODE.LOG_VIEW, "策略SDK初始化完成:", $YTSDK.tacticsSDK)

            $YTLOG(CONST_CODE.LOG_VIEW, "时间——策略SDK初始化完成:", Date.now())
        }

        if (!$YTSDK.reportSDK.reportSdkIsReady && $YTSDK.tacticsSDK.tacticsData) {
            //2.上报SDK
            $YTSDK.reportSDK.initReport($YTSDK.userData, $YTSDK.userDeviceData, $YTSDK.userLocalData,$YTSDK.tacticsSDK.tacticsData);
            $YTLOG(CONST_CODE.LOG_VIEW, "上报SDK初始化完成", $YTSDK.reportSDK, new Date())

            $YTLOG(CONST_CODE.LOG_VIEW, "时间——上报SDK初始化完成:", Date.now())

            //3.3 发起启动上报
            let reportParem = {
                ad_type: app.getInfo().source.type,
                page_type: String($YTSDK.tacticsSDK.tacticsData.number_of_visits),
                result: String($YTSDK.reportSDK.publicAttr.platform_code),
                ad_style: $YTSDK.userData.imei,
                element_name: $YTSDK.userDeviceData.oaid
            }
            ReportUtil.hap_report(reportParem)
        }

        if (!$YTSDK.adControl && $YTSDK.tacticsSDK.tacticsData) {
            //3.广告控制器

            $YTSDK.adControl = AdControl.initialization($YTSDK.tacticsSDK.tacticsData.sdkAdPosInfo)
            $YTLOG(CONST_CODE.LOG_VIEW, "广告控制器初始化完成:", $YTSDK.adControl)

            $YTLOG(CONST_CODE.LOG_VIEW, "时间——广告控制器初始化完成:", Date.now())
            //3.2 发起广告请求
            $YTSDK.adControl.startAdRequest()
            //3.3 发起激励视频请求
            $YTSDK.adControl.startVideoAd()
        }
        //前置条件准备完毕，允许加载广告池
        this.cxt.isShowPagePool = true;
    }


    //初始化页面信息
    async initPageInfo() {
        //1.当前页面信息
        let routeInfo = router.getState()
        let tempKey = ""
        if (routeInfo.path == "/pagesA/Main") {
            //3.1特殊处理首页
            tempKey = routeInfo.path + "?selectIndex=" + this.cxt.selectIndex
        } else {
            tempKey = routeInfo.path
        }
        this.cxt.pageInfo = RouteConfig.getPageInfoByRoute(tempKey)

        //2.来源页信息
        this.cxt.originPageInfo = await RouteConfig.getOriginPageInfo()

        if (!this.cxt.originPageInfo) {
            if ($YTSDK.userData.intent == "2") {
                //deeplink
                this.cxt.originPageInfo = await PageInfo.getDefaultOrigin("CHANNEL")
            } else if ($YTSDK.userData.intent == "3") {
                //通知栏点击
                this.cxt.originPageInfo = await PageInfo.getDefaultOrigin("NOTICE")
            } else {
                // 桌面启动
                this.cxt.originPageInfo = await PageInfo.getDefaultOrigin("DESK")
            }
        }
        await RouteConfig.updateOriginPageInfo(this.cxt.pageInfo)
    }


    initRouterConfig() {
        this.cxt.routerConfig = $YTSDK.tacticsSDK.getPageBackRouter(this.cxt.pageInfo.pageCode)
        $YTLOG(CONST_CODE.LOG_VIEW, "根据页面code获取路由信息:", this.cxt.routerConfig)
    }


    /**
     * 物理返回
     * isAllowBackPress 逻辑：进入页面且弹窗展示 开始计时 到达应用配置
    */
    onBackPress() {
        $YTLOG(CONST_CODE.LOG_VIEW, "页面生命周期:onBackPress")
        if (this.cxt.isAllowBackPress) {
            //弹窗关闭
            if (this.cxt.isShowPopup) {
                this.#closePopUp()
                let reportParam = {
                    page_type: this.cxt.popInfo.popGroupName,
                    ad_position: this.cxt.popInfo.popName,
                    page_url: this.cxt.pageInfo.pageUrl
                }
                ReportControl.backClickReport('关闭弹窗', reportParam)
                this.cusEventHandle("POPUP_CLOSE")
            } else {
                let popCode = this.#getPopCodeByEvent("PAGE_BACK")
                if (popCode) {
                    $YTLOG(CONST_CODE.LOG_VIEW, "触发返回事件:有弹窗", popCode)
                    //有返回弹窗
                    this.cxt.isAllowBackPress = false
                    this.cusEventHandle("PAGE_BACK")
                } else {
                    //无弹窗 按照路由信息返回
                    $YTLOG(CONST_CODE.LOG_VIEW, "返回路由", this.cxt.routerConfig)
                    $YTLOG(CONST_CODE.LOG_VIEW, "触发返回事件:无弹窗")
                    if (this.cxt.routerConfig) {
                        let reportParam = {
                            page_type: this.cxt.popInfo.popGroupName,
                            ad_position: this.cxt.popInfo.popName,
                            page_url: this.cxt.pageInfo.pageUrl
                        }
                        ReportControl.backClickReport('跳转页面', reportParam)

                        $YTLOG(CONST_CODE.LOG_VIEW, "物理返回跳转页面:", this.cxt.routerConfig)

                        this.#routeToPage(this.cxt.routerConfig)

                    }
                }
            }
        } else {
            let reportParam = {
                page_type: this.cxt.popInfo.popGroupName,
                ad_position: this.cxt.popInfo.popName,
                page_url: this.cxt.pageInfo.pageUrl
            }
            ReportControl.backClickReport('跳转页面', reportParam)
        }
        return true
    }

    /**
     * 处理自定义事件
    */
    async cusEventHandle(customEvent) {
        //有弹窗 不触发自定义事件
        if (this.cxt.isShowPopup) return false
        //弹窗逻辑
        let popCode = this.#getPopCodeByEvent(customEvent)
        $YTLOG(CONST_CODE.LOG_VIEW, "时间——弹窗Code获取完成:", Date.now(), popCode)

        if (popCode) {
            this.cxt.popCodeLast = popCode
            let popUpInfo = await $YTSDK.tacticsSDK.getPopupConfigInfoByCode(popCode)
            $YTLOG(CONST_CODE.LOG_VIEW, "时间——弹窗信息获取完成:", Date.now())
            if (popUpInfo.length > 0) {
                this.#showPopup(new PopUpInfo(popUpInfo[0]),customEvent);
                return true
            }
        } else {
            $YTLOG(CONST_CODE.LOG_VIEW, "未取到弹窗")
        }
        return false
    }

    /**
     * 展示弹窗 
     * 逻辑描述：
     *  根据弹窗信息展示弹窗
     *  有广告数据：展示
     *  无广告数据：添加订阅，等待通知
     * 
     * */
    async #showPopup(popUpInfo,customEvent) {
        //TODO:间隔200ms监测
        this.cxt.popInfo = popUpInfo
        $YTLOG(CONST_CODE.LOG_VIEW, "根据弹窗Code获取弹窗信息:", this.cxt.popCodeLast, this.cxt.popInfo)

        let adData = await StorageUtils.getItem("ClickAdData")

        if (!this.cxt.isShowPopup) {
            //弹窗配置 && 广告池中有数据
            $YTLOG(CONST_CODE.LOG_VIEW, "开始展示弹窗", this.cxt)
            if (this.cxt.popInfo) { //&& $YTSDK.adControl.dataPool.adNumInDataPool()
                this.cxt.isShowPopup = true;
                //设置延时
                this.#setPopBtnDelay()
                ReportControl.customPopupReport('show', adData, popUpInfo, this.cxt.pageInfo,"",customEvent)
                
                $YTLOG(CONST_CODE.LOG_VIEW, "时间——展示弹窗完成", Date.now())
                $YTLOG(CONST_CODE.LOG_VIEW, "展示弹窗完成", this.cxt.isShowPopup)
            } else {
                //添加订阅：广告池数据状态改变(hasAdDataChange)
                $YTSDK.pubsubEvent.subscribe("hasAdDataChange", (status) => {
                    $YTLOG(CONST_CODE.LOG_VIEW, "广告池数据状态改变", status)
                    if (!this.cxt.isShowPopup) {
                        this.cxt.isShowPopup = true;
                        //设置延时
                        this.#setPopBtnDelay()
                        ReportControl.customPopupReport('show', adData, popUpInfo, this.cxt.pageInfo,"",customEvent)
                        $YTLOG(CONST_CODE.LOG_VIEW, "展示弹窗成功", this.cxt.popCodeLast)
                    }
                })
            }
        }
    }


    //弹窗事件 正向按钮、负向按钮、关闭

    /**
     * 弹窗事件
     * 注意：仅处理业务相关事件：
     *  1.正向按钮点击(btnClick)
     *  2.负向按钮点击(negClick)
     *  3.返回按钮点击(backClick)
     *  4.关闭按钮点击(clsClick)
     * 逻辑：
     *  弹窗关闭之后，点击广告跟随变动，之后刷新广告
    */
    async popEvent(evt) {
        let pageInfo = this.cxt.pageInfo

        let popInfo = evt.detail.popInfo
        let event = evt.detail.event
        let adData = await StorageUtils.getItem("ClickAdData")

        $YTLOG(CONST_CODE.LOG_VIEW, "弹窗事件:", evt, this.cxt)
        switch (event) {
            //正向按钮
            case "btnClick":
                //正向按钮点击，需要根据配置执行不同行为
                this.#popEventDealWithJumpKey(popInfo)
                ReportControl.customPopupReport('click', adData, popInfo, pageInfo, '正向按钮')
                break;
            //返回按钮
            case "backClick":
                this.#closePopUp();
                ReportControl.customPopupReport('click', adData, popInfo, pageInfo, '返回按钮')
                this.cusEventHandle("POPUP_CLOSE")
                break;
            //负向按钮
            case "negClick":
                if (this.cxt.isAllowNegPress) {
                    //负向按钮点击，需要根据配置执行不同行为
                    this.#popEventDealWithJumpKey(popInfo)
                    ReportControl.customPopupReport('click', adData, popInfo, pageInfo, '负向按钮')
                }
                break;
            //关闭按钮
            case "clsClick":
                //关闭弹窗
                if (this.cxt.isAllowClosePress) {
                    this.#closePopUp();
                    //触发弹窗关闭事件
                    this.cusEventHandle("POPUP_CLOSE");
                    ReportControl.customPopupReport('click', adData, popInfo, pageInfo, '关闭按钮');
                }
                break;
        }
    }


    /**
     * 广告事件
     * 注意：仅处理业务相关事件：广告点击
    */
    adEvent(evt) {
        let adData = evt.detail.adData
        let event = evt.detail.event
        switch (event) {
            case "adClick":
                console.log('注意：仅处理业务相关事件：广告点击2', evt)
                $YTSDK.adControl.palyVideoAd()
                //广告点击触发弹窗正向按钮事件
                this.#popEventDealWithJumpKey(this.cxt.popInfo)
                ReportControl.customPopupReport('click', adData, this.cxt.popInfo, this.cxt.pageInfo, '正向按钮')
                break;
        }

        $YTLOG(CONST_CODE.LOG_VIEW, "广告事件", event, adData, adData.adData.adId, adData.adData.ecpm)
    }



    // 1 跳转新页面 2按策略路由返回  3退出应用  4关闭弹窗
    #popEventDealWithJumpKey(popInfo) {
        let uri
        let jumpKey = popInfo.btnStyle.jumpKey
        switch (jumpKey) {
            //1:跳转新页面
            case 1:
                uri = popInfo.btnStyle.jumpValue

                if (uri) {
                    this.#closePopUp();
                    this.#routeToPage(uri)
                }
                break;
            //2:按策略路由返回
            case 2:
                uri = this.cxt.routerConfig

                if (uri) {
                    this.#closePopUp();
                    this.#routeToPage(uri)
                } else {

                    this.#closePopUp();
                    this.cxt.$app.exit()
                }
                break;
            //3:退出应用
            case 3:

                this.#closePopUp();
                this.cxt.$app.exit()
                break;
            //4:关闭弹窗
            case 4:

                this.#closePopUp();
                this.cusEventHandle("POPUP_CLOSE");
                break;

        }
    }

    /**
     * 按策略路由返回
     * */
    #routeToPage(uri) {
        if (uri) {
            this.cxt.isShowPagePool = false
            router.replace({ uri })
        }
    }

    /**
     * 根据自定义事件来获取弹窗Code，以此来判断是够需要弹出弹窗
    */
    #getPopCodeByEvent(customEvent) {
        let popUpCode = $YTSDK.tacticsSDK.getPopupCodeByPageInfo(this.cxt.pageInfo.pageCode, this.cxt.originPageInfo.pageCode, customEvent, this.cxt.popCodeLast)
        if (popUpCode) {
            return popUpCode
        }
        return ""
    }


    /**
     * 设置弹窗按钮延迟生效
    */
    #setPopBtnDelay() {
        this.cxt.isAllowBackPress = false;
        setTimeout(() => {
            //允许物理返回
            this.cxt.isAllowBackPress = true;
            $YTLOG(CONST_CODE.LOG_VIEW, "延时生效 物理返回", this.cxt.isAllowBackPress)

        }, this.cxt.popInfo.commonStyle.backLockTime);
        setTimeout(() => {
            //允许关闭按钮
            this.cxt.isAllowClosePress = true;
            $YTLOG(CONST_CODE.LOG_VIEW, "延时生效 关闭按钮", this.cxt.isAllowClosePress)

        }, this.cxt.popInfo.closeStyle.delay);

        setTimeout(() => {
            //允许负向按钮
            this.cxt.isAllowNegPress = true;
            $YTLOG(CONST_CODE.LOG_VIEW, "延时生效 负向按钮", this.cxt.isAllowNegPress)
        }, this.cxt.popInfo.negStyle.delay);
    }



    /**
     * 关闭弹窗并清空热区
    */
    #closePopUp() {
        this.cxt.isShowPopup = false;
        $YTLOG(CONST_CODE.LOG_VIEW, "清空热区", $YTSDK.pubsubEvent)
        $YTSDK.pubsubEvent.publish("hotAreaChanged", {
            isClear: true
        })
    }
}